﻿// Copyright (C) Jari Hautio <jari.hautio@iki.fi> 2008. Licensed under GPLv2. See LICENSE.txt in solution folder.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;

namespace RyijyApp
{
    /// <summary>
    /// Helper class for handling color matrix.
    /// </summary>
    class MyColorMatrix
    {
        /// <summary>
        /// Internal color matrix.
        /// </summary>
        private ColorMatrix colorMatrix = new ColorMatrix();
        /// <summary>
        /// Set or get current color matrix.
        /// </summary>
        public ColorMatrix ColorMatrix { get { return colorMatrix; } set { colorMatrix = value; } }

        /// <summary>
        /// Contrast value. 1.0f is normal.
        /// </summary>
        float contrast = 1.0f;
        /// <summary>
        /// Saturation value. 1.0f is normal.
        /// </summary>
        float saturation = 1.0f;

        /// <summary>
        /// Resets color matrix to identity matrix
        /// </summary>
        public void Reset()
        {
            contrast = 1.0f;
            saturation = 1.0f;
            for (int i = 0; i < 25; i++)
                colorMatrix[i / 5, i % 5] = (i / 5 == i % 5) ? 1f : 0f;
        }

        /// <summary>
        /// Modify color contrast.
        /// </summary>
        /// <param name="s">Contrast. 1.0f is no change. Large value gives mor contrast.</param>
        /// <returns>New color matrix</returns>
        public ColorMatrix SetContrast(float s)
        {
            contrast = s;
            colorMatrix = GetColorMatrix(saturation, contrast);
            return colorMatrix;
        }

        /// <summary>
        /// Modify color saturation.
        /// </summary>
        /// <param name="s">Saturation. No change = 1.0f, BW=0.0f </param>
        /// <returns>New color matrix</returns>
        public ColorMatrix SetSaturation(float s)
        {
            saturation = s;
            colorMatrix = GetColorMatrix(saturation, contrast);
            return colorMatrix;
        }

        /// <summary>
        /// Calculates color matrix with given saturation and contrast values
        /// </summary>
        /// <param name="s">Saturation</param>
        /// <param name="f">Contrast</param>
        /// <returns>New color matrix</returns>
        public static System.Drawing.Imaging.ColorMatrix GetColorMatrix(float s, float f)
        {
            // from http://www.graficaobscura.com/matrix/index.html
            float rw = (1.0f - s) * 0.3086f ;
            float gw = (1.0f - s) * 0.6094f ;
            float bw = (1.0f - s) * 0.0820f ;

            // without this tweak pushing contrast up caused color anomality.
            if (rw == 0 && f > 1.0f) rw = 0.0001f; 

            return new System.Drawing.Imaging.ColorMatrix(new float[][] {
                new float[]{f*(rw+s),   rw,   rw, 0.0f, 0.0f},
                new float[]{  gw, f*(gw+s),   gw, 0.0f, 0.0f},
                new float[]{  bw,   bw, f*(bw+s), 0.0f, 0.0f},
                new float[]{0.0f, 0.0f, 0.0f, 1.0f, 0.0f},
                new float[]{0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
            });
        }
        
    }
}
